package com.netcracker.studportal.server.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;

public class FileUtil {
	/**
	 * Path to directory on the server which contains files with materials.
	 */
	public static final String PATH_TO_ROOT_DIRECTORY = "./filestorage/materials/";

	/**
	 * Method for decoding file from string and storing on server.
	 * 
	 * @param fileContent
	 * 				- encoding file in string
	 * @param fileName 
	 * 				- name for storing file
	 * 
	 * @return path to stored file
	 * @throws Exception
	 */

	public static String decodeAndSaveFile(String fileContent, String fileName) throws Exception {
		if (StringUtils.isEmpty(fileContent)) {
			throw new IllegalArgumentException("String with file content cannot be empty!");
		}
		
		if (StringUtils.isEmpty(fileName)) {
			throw new IllegalArgumentException("Name for storing file cannot be empty!");
		}
		
		if (!validateRootDirectory()) {
			throw new RuntimeException("Directory of file storage with path = " + PATH_TO_ROOT_DIRECTORY + " doesn't exist!");
		}
		
		FileOutputStream outFile = null;
		try {		
			byte[] fileArr = decodeStringToByteArr(fileContent);
			
			File file = new File(PATH_TO_ROOT_DIRECTORY + fileName);
			
			outFile = new FileOutputStream(file);

			outFile.write(fileArr);

			return file.getPath();
		} catch (Exception e) {
			throw e;
		} finally {
			if (outFile != null) {
				outFile.close();
			}
		}
	}

	/**
	 * Method for loading file from server and encoding it.
	 * @param pathToFile
	 * 				- path to stored file
	 * @return string which contains encoded file content
	 * @throws Exception
	 */
	public static String loadAndEncodeFile(String pathToFile) throws Exception {
		if (StringUtils.isEmpty(pathToFile)) {
			throw new IllegalArgumentException("Path to loading file cannot be empty!");
		}
		
		if (!validateRootDirectory()) {
			throw new RuntimeException("Directory of file storage with path = " + PATH_TO_ROOT_DIRECTORY + " doesn't exist!");
		}
		
		FileInputStream inFile = null;
		try {
			File file = new File(pathToFile);
			
			inFile = new FileInputStream(file);
			
			byte[] fileArr = new byte[(int) file.length()];
			
			inFile.read(fileArr);

			String dataString = encodeByteArrToString(fileArr);

			return dataString;
		} catch (Exception e) {
			throw e;
		} finally {
			if (inFile != null) {
				inFile.close();
			}
		}
	}

	/**
	 * Encodes the byte array into base64 string.
	 * 
	 * @param byteArray
	 *            - byte array
	 * @return string which contains encoded file content
	 */
	public static String encodeByteArrToString(byte[] byteArray) {
		return Base64.encodeBase64URLSafeString(byteArray);
	}

	/**
	 * Decodes the base64 string into byte array.
	 * 
	 * @param dataString
	 *            - string which contains encoded file content
	 * @return byte array
	 */
	public static byte[] decodeStringToByteArr(String dataString) {
		return Base64.decodeBase64(dataString);
	}
	
	/**
	 * Method for checking that root directory exists. If directory is not exist - create it.
	 * @return true - if root directory exists, false - if not exists
	 */
	private static boolean validateRootDirectory() {
		File rootDirectory = new File(PATH_TO_ROOT_DIRECTORY);
		if (rootDirectory.exists()) {
			return true;
		} else {
			// try to create directory
			return rootDirectory.mkdirs();
		}
	}
	
	public static void deleteFile(String filePath) throws Exception{
		if (StringUtils.isEmpty(filePath)) {
			throw new IllegalArgumentException("Path of file cannot be empty!");
		}
		
		File file = new File(filePath);
			
			Boolean b=file.delete();
		    if(!b) throw new Exception("Error of deleting file!");		
	}
	
}
